package com.darkflame.client.query;

import java.util.Collection;
import java.util.HashSet;

import com.darkflame.client.semantic.SSSNode;
import com.darkflame.client.semantic.SSSProperty;

/** a Query element is a single requirement of a query
 * This is either a SSSProperty, or another Query **/

public class QueryElement {
		
	public QuerySSSProperty prop;
	public Query query;
	
	
	public QueryElement(QuerySSSProperty prop) {
		super();
		this.prop = prop;
	}
	public QueryElement(Query query) {
		super();
		this.query = query;
	}
	public QueryElement(SSSProperty prop) {
		super();
		this.prop = new QuerySSSProperty(prop.getPred(), prop.getValue() );
	}
	
	public String getAsString(){
		
		if (query!=null){
			String Inverse = "";
			if (query.invertResults){
				 Inverse = "!" ;				
			} 
			return Inverse+"("+query.getAsString()+")";
			
		}
		
		String Pred = "";
		String Value = "";
		
		if (prop.getPred()!=null){
			Pred = prop.getPred().PURI;			
		}
		if (prop.getValue()!=null){
			Value = prop.getValue().PURI;			
		}
		
		if (prop.getQueryForPred()!=null){
			Pred = "("+prop.getQueryForPred().getAsString()+")";
		}
		if (prop.getQueryForValue()!=null){
			Value = "("+prop.getQueryForValue().getAsString()+")";
		}
		
		return Pred+"<~"+Value;
	}
	
	public boolean hasError() {		
		
		//if there's a query then there wont be a prop, so we test for this first		
		if (query!=null){
			if (!query.hasNoErrors()){
				return true;
			} else {
				return false;
			}
		}
		
		if (prop.getPred()==SSSNode.NOTFOUND){
			return true;
		}
		if (prop.getValue()==SSSNode.NOTFOUND){
			return true;
		}
		
	
		return false;
	}
	
	public HashSet<SSSNode> getAllUsedNodes() {
		
		HashSet<SSSNode> nodesused = new HashSet<SSSNode>();
		
		if (query!=null){
			//add nodes from subquery
			nodesused.addAll(query.allUsedNodes());
			return nodesused;
		}
		//else add these nodes
		nodesused.add(this.prop.getPred());
		nodesused.add(this.prop.getValue());
		
		
		
		return nodesused;
	}
}